#ifndef THREADSAFELIST_H
#define THREADSAFELIST_H
//#include "utilityTool/log4z.h"
//#include <windows.h>
#include<deque>
//#include"utilityTool/tool_function.h"

#ifdef _WIN32
#include <Windows.h>

class MySafeLocker
{
public:
    MySafeLocker(CRITICAL_SECTION* inHandle) : m_handle(inHandle)
    {
        if (NULL != m_handle)
        {
            EnterCriticalSection(m_handle);
        }
    }

    ~MySafeLocker()
    {
        if (NULL != m_handle)
        {
            LeaveCriticalSection(m_handle);
            m_handle = NULL;
        }
    }
private:
    CRITICAL_SECTION* m_handle;
};
#else
#include <pthread.h>

typedef struct ThreadMutex
{
	ThreadMutex()
	{
		pthread_mutex_init(&mtx, NULL);
	}
	~ThreadMutex()
	{
		pthread_mutex_destroy(&mtx);
	}
	inline void lock()
	{

		pthread_mutex_lock(&mtx);
		//    printf("Enter %d\n", ++i);
	}
	inline void unlock()
	{
		pthread_mutex_unlock(&mtx);
		//     printf("Leave %d\n", ++t);
	}
	pthread_mutex_t mtx;
	//   int i;
	//   int t;
}ThreadMutex;


class MySafeLocker
{
public:
    MySafeLocker(ThreadMutex* inHandle) : m_handle(inHandle)
    {
        if (NULL != m_handle)
        {
            m_handle->lock();
        }
    }

    ~MySafeLocker()
    {
        if (NULL != m_handle)
        {
            m_handle->unlock();
            m_handle = NULL;
        }
    }
private:
    ThreadMutex* m_handle;
};

#endif

template <typename T>
class TemplateThreadSafeList
{
public:
    TemplateThreadSafeList();
    ~TemplateThreadSafeList();

public:
    size_t size();
    bool empty();
    void clear();

    T front();
    void pop_front();
    void pop_back();
    void push_back(T result);
	bool get_front_and_pop(T& result);
private:
#ifdef _WIN32
    CRITICAL_SECTION m_hcs;
#else
	ThreadMutex m_hcs;
#endif
    std::deque<T> m_list;
    
    friend class MySafeLocker;
};

template <typename T>
bool TemplateThreadSafeList<T>::get_front_and_pop(T& result)
{
	try
	{
		MySafeLocker locker(&m_hcs);
		if (m_list.empty())
		{
			return false;
		}
		result = m_list.front();
		m_list.pop_front();
		return true;
	}
	catch (std::bad_exception& e)
	{
		printf("%s, bad_exception, error msg = %s",__FUNCTION__, e.what());
		return false;
	}
	catch (std::bad_alloc& e)
	{
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
		return false;
	}
	catch (std::exception& e)
	{
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
		return false;
	}
	catch (void*)
	{
		printf("%s,  void* exception", __FUNCTION__);
		return false;
	}
	catch (...)
	{
		printf("%s,  unknown exception", __FUNCTION__);
		return false;
	}
	//if (m_list.empty())
	//{
	//	return false;
	//}
	//result =  m_list.front();
	//m_list.pop_front();
	return true;
}

template <typename T>
void TemplateThreadSafeList<T>::clear()
{   
	try
	{
		MySafeLocker locker(&m_hcs);
		m_list.clear();
	}
	catch (std::bad_exception& e)
	{
		printf("%s, bad_exception, error msg = %s",__FUNCTION__,  e.what());
	}
	catch (std::bad_alloc& e)
	{
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
	}
	catch (std::exception& e)
	{
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
	}
	catch (void*)
	{
		printf("%s,  void* exception", __FUNCTION__ );
	}
	catch (...)
	{
		printf("%s,  unknown exception", __FUNCTION__);
	}    
}

template <typename T>
size_t TemplateThreadSafeList<T>::size()
{    
	try
	{
		MySafeLocker locker(&m_hcs);
		return m_list.size();
	}
	catch (std::bad_exception& e)
	{
		printf("%s, bad_exception, error msg = %s", __FUNCTION__, e.what());
		return 0;
	}
	catch (std::bad_alloc& e)
	{
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
		return 0;
	}
	catch (std::exception& e)
	{
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
		return 0;
	}
	catch (void*)
	{
		printf("%s,  void* exception",__FUNCTION__ );
		return 0;
	}
	catch (...)
	{
		printf("%s,  unknown exception",__FUNCTION__ );
		return 0;
	}
}

template <typename T>
bool TemplateThreadSafeList<T>::empty()
{
	try
	{
		MySafeLocker locker(&m_hcs);

		return m_list.empty();
	}
	catch (std::bad_exception& e)
	{
		printf("%s, bad_exception, error msg = %s", __FUNCTION__, e.what());
	}
	catch (std::bad_alloc& e)
	{
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
	}
	catch (std::exception& e)
	{
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
	}
	catch (void*)
	{
		printf("%s,  void* exception", __FUNCTION__ );
	}
	catch (...)
	{
		printf("%s,  unknown exception", __FUNCTION__ );
	}
}

template <typename T>
T TemplateThreadSafeList<T>::front()
{
    try
    {
        //std::unique_lock<std::mutex> locker(m_mtx);
        MySafeLocker locker(&m_hcs);
        T value;
        if (!m_list.empty())
        {
            value = m_list.front();
        }
        return value;
    }
    catch (std::bad_exception& e)
    {
		printf("%s, bad_exception, error msg = %s", __FUNCTION__, e.what());
        return T();
    }
    catch (std::bad_alloc& e)
    {
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
        return T();
    }
    catch (std::exception& e)
    {
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
        return T();
    }
    catch (void*)
    {
		printf("%s,  void* exception", __FUNCTION__ );
        return T();
    }
    catch (...)
    {
		printf("%s,  unknown exception", __FUNCTION__ );
        return T();
    }
}

template <typename T>
void TemplateThreadSafeList<T>::pop_front()
{
    try
    {
        //std::unique_lock<std::mutex> locker(m_mtx);
        MySafeLocker locker(&m_hcs);

        if (!m_list.empty())
        {
            m_list.pop_front();
        }
    }
    catch (std::bad_exception& e)
    {
		printf("%s, bad_exception, error msg = %s", __FUNCTION__, e.what());
    }
    catch (std::bad_alloc& e)
    {
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
    }
    catch (std::exception& e)
    {
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
    }
    catch (void*)
    {
		printf("%s,  void* exception", __FUNCTION__ );
    }
    catch (...)
    {
		printf("%s,  unknown exception", __FUNCTION__ );
    }
}

template <typename T>
void TemplateThreadSafeList<T>::pop_back()
{
    try
    {
        //std::unique_lock<std::mutex> locker(m_mtx);
        MySafeLocker locker(&m_hcs);

        if (!m_list.empty())
        {
            m_list.pop_back();
        }
    }
    catch (std::bad_exception& e)
    {
		printf("%s, bad_exception, error msg = %s", __FUNCTION__, e.what());
    }
    catch (std::bad_alloc& e)
    {
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
    }
    catch (std::exception& e)
    {
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
    }
    catch (void*)
    {
		printf("%s,  void* exception", __FUNCTION__ );
    }
    catch (...)
    {
		printf("%s,  unknown exception",__FUNCTION__ );
    }
}

template <typename T>
void TemplateThreadSafeList<T>::push_back(T result)
{
    try
    {
        //std::unique_lock<std::mutex> locker(m_mtx);
        MySafeLocker locker(&m_hcs);

        m_list.push_back(result);
    }
    catch (std::bad_exception& e)
    {
		printf("%s, bad_exception, error msg = %s", __FUNCTION__, e.what());
    }
    catch (std::bad_alloc& e)
    {
		printf("%s, bad_alloc, error msg = %s", __FUNCTION__, e.what());
    }
    catch (std::exception& e)
    {
		printf("%s, exception, error msg = %s.", __FUNCTION__, e.what());
    }
    catch (void*)
    {
		printf("%s,  void* exception", __FUNCTION__);
    }
    catch (...)
    {
		printf("%s,  unknown exception", __FUNCTION__);
    }
}

template <typename T>
TemplateThreadSafeList<T>::~TemplateThreadSafeList()
{
#ifdef _WIN32
    DeleteCriticalSection(&m_hcs);
#else
#endif
}

template <typename T>
TemplateThreadSafeList<T>::TemplateThreadSafeList()
{
#ifdef _WIN32
    InitializeCriticalSection(&m_hcs);
#else
#endif
}


#endif
